package se.webbzon.oschi01.modelset;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

import javax.media.j3d.SharedGroup;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Vector3d;

import se.webbzon.oschi01.resourceset.ResourceSetLoaderException;

import com.sun.j3d.loaders.IncorrectFormatException;
import com.sun.j3d.loaders.ParsingErrorException;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;

public class WavefrontObjectSetLoader extends Model3DSetLoader {
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public boolean supportsAddFromURL() {
		return true;
	}
	
	@Override public boolean addFromURL(URL resourceURL) 
			throws ResourceSetLoaderException {
		ObjectFile objectFile = new ObjectFile(ObjectFile.RESIZE | ObjectFile.STRIPIFY);
		try {
			Scene scene = objectFile.load(resourceURL);
			return addResource(new WavefrontObjectModel3D(scene));
		} catch (	FileNotFoundException | IncorrectFormatException | 
					ParsingErrorException e) {
			throw new ResourceSetLoaderException(e);
		}
	}
	
	@Override public boolean supportsAddFromInputStream() {
		return true;
	}
	
	@Override public boolean addFromInputStream(InputStream inputStream) 
			throws ResourceSetLoaderException {
		ObjectFile objectFile = new ObjectFile(ObjectFile.RESIZE | ObjectFile.STRIPIFY);
		InputStreamReader reader = new InputStreamReader(inputStream);
		try {
			Scene scene = objectFile.load(reader);
			return addResource(new WavefrontObjectModel3D(scene));
		} catch (	IOException |IncorrectFormatException | ParsingErrorException e) {
			throw new ResourceSetLoaderException(e);
		}
	}
	
	/*============================================================
	Private Classes
	============================================================*/
	
	private static final class WavefrontObjectModel3D extends Model3D {
		
		// The shared group containing the model 
		private final SharedGroup sharedGroup;

		/*============================================================
		Constructors
		============================================================*/
		
		/** Creates a new Model3D from a Java3D Scene instance. **/
		private WavefrontObjectModel3D(Scene wavefrontObjectScene) {
			sharedGroup = new SharedGroup();
			
			// Scale the model
			TransformGroup transformGroup = new TransformGroup();
			final Transform3D transform = new Transform3D();
			final Vector3d scaling = new Vector3d(0.5,0.5,0.5);
			transform.setScale(scaling);
			transformGroup.setTransform(transform);
			transformGroup.addChild(wavefrontObjectScene.getSceneGroup());
			
			sharedGroup.addChild(transformGroup);
			sharedGroup.compile();
		}
		
		/*============================================================
		Public Methods
		============================================================*/

		@Override public SharedGroup getSharedGroup() {
			return sharedGroup;
		}
		
	}

}
